﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TiposComuns.Objectos;
using Servidor.WebServices;
using System.Runtime.Remoting.Messaging;
using System.Threading;

namespace Servidor.Interface
{
    delegate State RefreshDelegate();
    delegate void RefreshForm();
    delegate void RefreshLogDelegate(string msg);
    public partial class StateForm : Form
    {
        private State state;
        private Label[] lb = new Label[3];
        private Label[] lbprim = new Label[3];
        private bool[] flag = new bool[3];
        private System.Threading.Timer timer;
        private int freezetime;

        public StateForm(State state, decimal server, Person person,string logfile)
        {
            Proxy.GetInstance().ActionDelegate += new ActionDelegate(UpdateLog);
            InitializeComponent();
            this.rtb_log.Text = logfile;
            this.state = state;
            tb_servID.Text = server.ToString();
            tb_username.Text = person.Username;
            tb_address.Text = person.Address.URI + ":" + person.Address.Port;
            flag[0] = false;
            flag[1] = false;
            flag[2] = false;
            lb[0] = lb_serv1;
            lb[1] = lb_serv2;
            lb[2] = lb_serv3;
            lbprim[0] = lb_prim1;
            lbprim[1] = lb_prim2;
            lbprim[2] = lb_prim3;
            this.RefreshState();       
            
            /* debug 
            List<Post> l = Proxy.GetInstance().PostsSince(0);
            foreach (Post p in l)
            {
                Console.WriteLine("post-> " + p.Message);
            }
            */
            
        }

        private void UpdateLog(string msg)
        {
            if (!this.IsDisposed)
            {
                this.Invoke(new RefreshLogDelegate(RefreshLog), msg);
            }
        }

        private void RefreshLog(string msg)
        {
            this.rtb_log.AppendText(System.Environment.NewLine+msg);
        }

        private void RefreshState()
        {
            flag[0] = false;
            flag[1] = false;
            flag[2] = false;
            if (state.View.ViewState.Count > 0)
            {
                int prim = state.View.ViewState[0];
                lb[prim].ForeColor = Color.Green;
                flag[prim] = true;
                switch(prim)
                {
                    case 0: lbprim[0].Visible = true;
                            lbprim[1].Visible = false;
                            lbprim[2].Visible = false; 
                            break;
                    case 1: lbprim[0].Visible = false;
                            lbprim[1].Visible = true;
                            lbprim[2].Visible = false;
                            break;
                    case 2: lbprim[0].Visible = false;
                            lbprim[1].Visible = false;
                            lbprim[2].Visible = true;
                            break;
                }
                if ((prim + 1).ToString() == tb_servID.Text)
                {
                    panel1.Visible = false;
                }
                else
                {
                    panel1.Visible = true;
                }
            }
            
            for (int i = 1; i < state.View.ViewState.Count; i++)
            {
                lb[state.View.ViewState[i]].ForeColor = Color.Green;
                flag[state.View.ViewState[i]] = true;
            }

            for (int i = 0; i < 3; i++)
            {
                if (!flag[i])
                {
                    lb[i].ForeColor = Color.Red;
                }
            }
            b_refresh.Enabled = true;
            tb_VID.Text = state.View.VID.ToString();
            tb_msgID.Text = state.IdMensagem.ID.ToString();

        }

        private void Callback(IAsyncResult res)
        {
            RefreshDelegate del = ((AsyncResult)res).AsyncDelegate as RefreshDelegate;
            this.state = del.EndInvoke(res);
            this.Invoke(new RefreshForm(this.RefreshState));
        }

        private void b_refresh_Click(object sender, EventArgs e)
        {
            b_refresh.Enabled = false;
            AsyncCallback ac = new AsyncCallback(Callback);

            RefreshDelegate del = new RefreshDelegate(Proxy.GetInstance().GetState);
            del.BeginInvoke(ac, null);            
        }

        private void StateForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Proxy.GetInstance().Desliga();
            if(this.Owner!= null)
                Owner.Show();
        }

        private void StateForm_Load(object sender, EventArgs e)
        {

        }

        private void bt_freeze_Click(object sender, EventArgs e)
        {
            int delay, ftime;
            if (!int.TryParse(tb_freezeperiod.Text, out ftime) || ftime <= 0)
            {
                MessageBox.Show("Freeze period errado");
                return;
            }

            if (!int.TryParse(tb_delay.Text, out delay)||delay<=0) 
            {
                MessageBox.Show("Delay errado");
                return;
            }

            Proxy.GetInstance().FreezeStart(delay);
            freezetime = ftime;

            TimerCallback tc = new TimerCallback(timer_Tick);
            timer = new System.Threading.Timer(tc, null, 1000, 1000);            
            
            bt_freeze.Enabled = false;
            tb_freezeperiod.ReadOnly = true;
            tb_delay.ReadOnly = true;
        }

        void RefreshFreeze()
        {
            tb_freezeperiod.Text = freezetime.ToString();
        }

        void EndFreeze()
        {
            tb_freezeperiod.Text = "";
            tb_delay.Text = "";
            bt_freeze.Enabled = true;
            tb_freezeperiod.ReadOnly = false;
            tb_delay.ReadOnly = false;            
        }

        void timer_Tick(object sender)
        {
            freezetime--;
            if (freezetime > 0)
            {
                this.Invoke(new RefreshForm(RefreshFreeze));                
            }
            else
            {
                timer.Dispose();
                Proxy.GetInstance().FreezeStop();
                this.Invoke(new RefreshForm(EndFreeze));
            }
        }
    }
}
